package com.akjava.vocaloidtools.wavtovsq;

import com.akjava.akjbetas.vocaloid.VoiceSettingPage;
import com.akjava.akjbetas.vocaloid.WavToVsqSettingPage;

import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DropTarget;
import org.eclipse.swt.dnd.DropTargetAdapter;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.dnd.FileTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.UnsupportedAudioFileException;

import jp.sourceforge.akjrcp.akj_betas.Akj_betasPlugin;
import jp.sourceforge.akjrcp.akj_betas.Messages;
import jp.sourceforge.akjrcp.audio.Scale;
import jp.sourceforge.akjrcp.audiotools.AudioToolsSettingPage;
import jp.sourceforge.akjrcp.audiotools.WaveFormViewer;
import jp.sourceforge.akjrcp.commons.ui.FileDirChoicer;
import jp.sourceforge.akjrcp.commons.ui.AbstractFileDirChoicer.FileStatusChangeEvent;
import jp.sourceforge.akjrcp.commons.ui.AbstractFileDirChoicer.FileStatusChangeListener;
import jp.sourceforge.akjrcp.commons.ui.widget.LayoutBuilder;
import jp.sourceforge.akjrcp.commons.ui.widget.WidgetBuilder;
import jp.sourceforge.akjrcp.commons.util.DetectUtils;
import jp.sourceforge.akjrcp.commons.util.FileNameUtils;
import jp.sourceforge.akjrcp.ffmpeg.FFMpegCommandUtil;
import jp.sourceforge.akjrcp.ffmpeg.FFMpegUI;
import jp.sourceforge.akjrcp.ffmpeg.FFMpegUtils;
import jp.sourceforge.akjrcp.ffmpeg.SimpleCommandExecuter;
import jp.sourceforge.akjrcp.snack.ESPS;
import jp.sourceforge.akjrcp.snack.PitchExecuter;
import jp.sourceforge.akjrcp.snack.PitchToVocaloidMIDI;
import jp.sourceforge.akjrcp.subtitle.StandardSubObject;
import jp.sourceforge.akjrcp.subtitle.SubtitleUtils;
import jp.sourceforge.akjrcp.subtitle.srt.SRTList;
import jp.sourceforge.akjrcp.subtitle.srt.SRTParser;
import jp.sourceforge.akjrcp.tools.OtherToolsSettingPage;
import jp.sourceforge.akjrcp.ui.param.DefaultParamOptionEditor;
import jp.sourceforge.akjrcp.ui.param.ParamBoolean;
import jp.sourceforge.akjrcp.ui.param.ParamCombo;
import jp.sourceforge.akjrcp.ui.param.ParamItem;
import jp.sourceforge.akjrcp.ui.param.ParamItemActionListener;
import jp.sourceforge.akjrcp.ui.param.ParamScale;
import jp.sourceforge.akjrcp.ui.param.ParamSpinner;
import jp.sourceforge.akjrcp.ui.param.ParamSpinnerAndScale;
import jp.sourceforge.akjrcp.ui.param.ParamText;
import jp.sourceforge.akjrcp.ui.param.ParamTextArea;
import jp.sourceforge.akjrcp.util.ExecutingControler;
import jp.sourceforge.akjrcp.util.StatusBarUtils;
import jp.sourceforge.akjrcp.util.ExecutingControler.ExecutingControlButton;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


public class WavToVocaloidMidiViewer extends ViewPart {
	public static Log log=LogFactory.getLog(WavToVocaloidMidiViewer.class);
	
	public static final String ID = WavToVocaloidMidiViewer.class.getName();
	private ParamCombo min_picth;
	private ParamCombo max_pitch;

	private FileDirChoicer tmpDirChooser;
	private FileDirChoicer inputWavFileChooser;
	private FileDirChoicer inputSrtFileChooser;
	
	private FileDirChoicer outputFileChooser;
	private WavToVocaloidMIDIExecute wavToMidiExecuter;
	
	private ParamSpinnerAndScale minVolumeScale;
	private ParamScale noteShiftScale;

	private Label statusLabel;

	private ParamBoolean forceInsertSubtile;

	private ParamBoolean ignoreOffsetBoolean;
	
	private ParamBoolean setPitchBoolean;
	private ParamBoolean setVelocityBoolean;

	private ParamScale strechTimeSale;



	private ParamSpinner defaultNoteSpinner;

	//private ParamSpinner defaultVelocitySpinner; //replaced voice vel

	private ParamCombo bentSens;
	private ParamCombo preMeasure;
	
	private ParamScale velScale;
	private ParamScale breScale;
	private ParamScale briScale;
	private ParamScale cleScale;
	private ParamScale opeScale;
	private ParamScale porScale;
	private ParamScale genScale;

	private ParamBoolean setPitchDetailBoolean;

	private ParamBoolean setVelocityDetailBoolean;

	private ParamCombo smoothLevel;
	
	private ParamBoolean vocaloid1;

	private ParamCombo filterCodeCombo;
	
	private ParamCombo noPitchMode;
	private ParamCombo noPitchAlternative;

	private ParamCombo upfilterCodeCombo;

	private ParamCombo downfilterCodeCombo;

	private ParamCombo downMixerScale;

	private ParamCombo upMixerScale;

	private ParamCombo averageLevel;

	private ParamCombo dynamicsAverageLevel;

	private ParamBoolean roundPitch;

	private ParamCombo finalPitchAverageLevel;

	private ParamCombo dynamicOverdrive;
	
	private ParamBoolean makeStereoTrack;

	private ParamCombo stereoMixerScale;

	private ParamBoolean splitBlessTrack;

	private ParamBoolean copyAsBlessTrack;

	private ParamBoolean autoNPhonetics;

	private ParamCombo copyAsBreathPhonetics;

	private ParamCombo copyAsBreathPhonetics2;

	private ParamBoolean ignoreBreathDynamics;

	private ParamScale fixedBreathDynamicsValue;

	private ParamBoolean doubleBreathTrack;

	private ParamScale stereoPanScale;

	private ParamBoolean doubleBreathTrack_split;
	
	public static final String IGNORE_AREA_MARK="*";
	public class ExportFileSet implements FileStatusChangeListener{

		public void addList(FileStatusChangeEvent event) {
			String path=event.getFilePath();
			if(!path.equals("")){
				setInputWave(path);
			}else{
				updateStatus();
			}
			
		}

		public void removeList(FileStatusChangeEvent event) {
			// TODO Auto-generated method stub
			
		}

	
		
	}
	
	public void createPartControl(Composite parent) {
		
		wavToMidiExecuter = new WavToVocaloidMIDIExecute();
		
		parent.setLayout(new GridLayout(1,false));
		
		
		
FileSelected selectedListener=new FileSelected();
Composite r1=createSplitComposite(parent,2,false,new GridData(GridData.FILL_HORIZONTAL));
r1.setLayout(LayoutBuilder.makeGridLayoutNoMargin(2, false));

		tmpDirChooser = new FileDirChoicer(r1,SWT.BORDER,FileDirChoicer.DIR,Messages.getString("spumux.tmp_dir"));
		tmpDirChooser.setToolTipText(Messages.getString("spumux.tmp_dir_tooltips"));
		tmpDirChooser.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		tmpDirChooser.addFileListChangeListener(selectedListener);
		
		tmpDirChooser.setFilePath(Akj_betasPlugin.getDefault().getPreferenceStore().getString(OtherToolsSettingPage.PATH_ASCII_TEMPORARY));
		tmpDirChooser.addFileListChangeListener(new FileStatusChangeListener(){

			public void addList(FileStatusChangeEvent event) {
				Akj_betasPlugin.getDefault().getPreferenceStore().setValue(OtherToolsSettingPage.PATH_ASCII_TEMPORARY, tmpDirChooser.getAbsoluteFilePath());
			}

			public void removeList(FileStatusChangeEvent event) {
				Akj_betasPlugin.getDefault().getPreferenceStore().setValue(OtherToolsSettingPage.PATH_ASCII_TEMPORARY, tmpDirChooser.getAbsoluteFilePath());
				
			}});
		

		
		
		CTabFolder tabFolder=new CTabFolder(parent,SWT.BOTTOM);
		CTabItem item1=new CTabItem(tabFolder,SWT.NULL);
		
		Composite twoComposite=WidgetBuilder.createGridLayoutComposite(tabFolder, SWT.NULL,2,false);
		
		Composite basicComposite=WidgetBuilder.createGridLayoutComposite(twoComposite, SWT.NULL);
		basicComposite.setLayoutData(new GridData(GridData.FILL_VERTICAL));
		item1.setControl(twoComposite);
		item1.setText(Messages.getString("wav2vsq.basic"));
		
		WavToVSQSettingList settingList=new WavToVSQSettingList(twoComposite,SWT.BORDER,WavToVsqSettingPage.PREFERENCE_KEY,Akj_betasPlugin.getDefault().getPreferenceStore());
		
		settingList.setLayoutData(new GridData(GridData.FILL_BOTH));
		DefaultParamOptionEditor editor=new DefaultParamOptionEditor();
		settingList.createControls(editor);
		//
		
		
		
		
		CTabItem item2=new CTabItem(tabFolder,SWT.NULL);
		Composite trackComposite=WidgetBuilder.createGridLayoutComposite(tabFolder, SWT.NULL);
		item2.setControl(trackComposite);
		item2.setText(Messages.getString("wav2vsq.track"));
		
		CTabItem item3=new CTabItem(tabFolder,SWT.NULL);
		Composite voiceComposite=WidgetBuilder.createGridLayoutComposite(tabFolder, SWT.NULL);
		item3.setControl(voiceComposite);
		item3.setText(Messages.getString("wav2vsq.voice"));
		
		CTabItem item5=new CTabItem(tabFolder,SWT.NULL);
		Composite breathComposite=WidgetBuilder.createGridLayoutComposite(tabFolder, SWT.NULL);
		item5.setControl(breathComposite);
		item5.setText(Messages.getString("wav2vsq.breath"));
		
		CTabItem item4=new CTabItem(tabFolder,SWT.NULL);
		Composite advancedComposite=WidgetBuilder.createGridLayoutComposite(tabFolder, SWT.NULL);
		item4.setControl(advancedComposite);
		item4.setText(Messages.getString("wav2vsq.advanced"));
		
		
		tabFolder.setSelection(0);//
		
		//basic composite
		Composite basic_upper=createSplitComposite(basicComposite,3,false,new GridData(GridData.FILL_HORIZONTAL));
		basic_upper.setLayout(LayoutBuilder.makeGridLayoutNoMargin(3, false));
		
		Group analyze=new Group(basicComposite,SWT.NULL);
		analyze.setText(Messages.getString("wav2vsq.analyze"));
		analyze.setLayout(LayoutBuilder.makeGridLayoutNoMargin(3, false));
		

		//Composite s3=createSplitComposite(parent,6,false,new GridData(GridData.FILL_HORIZONTAL));
		
		setPitchBoolean = new ParamBoolean(analyze,SWT.NULL,"set_pitch",Messages.getString("wav2midi.set_pitch"));
		setPitchBoolean.setValue("1");
		editor.addParamList(setPitchBoolean);
		//setPitchBoolean.setEnabled(false);//bug 
		
		setPitchDetailBoolean = new ParamBoolean(analyze,SWT.NULL,"pitch_detail",Messages.getString("wav2midi.set_pitch_detail"));
		setPitchDetailBoolean.setValue("1");
		editor.addParamList(setPitchDetailBoolean);
		
		setVelocityDetailBoolean = new ParamBoolean(analyze,SWT.NULL,"velocity_detail",Messages.getString("wav2midi.set_velocity_detail"));
		setVelocityDetailBoolean.setValue("0");
		editor.addParamList(setVelocityDetailBoolean);
		
		
		
		
		
		Group average=new Group(basicComposite,SWT.NULL);
		average.setText(Messages.getString("wav2vsq.average"));
		average.setLayout(LayoutBuilder.makeGridLayoutNoMargin(3, false));
		

		averageLevel = new ParamCombo(average,SWT.NULL,"averageLevel",Messages.getString("wav2vsq.averageLevel"),new String[]{"0","1","2","3","4","5","6","7","8","9","10","12","14","16","18","20","24","28","40","60","120","240"});
		averageLevel.setValue("4");
		averageLevel.setToolTipText(Messages.getString("wav2vsq.averageLevel_tooltip"));
		editor.addParamList(averageLevel);
		
		finalPitchAverageLevel = new ParamCombo(average,SWT.NULL,"finalPitchAverageLevel",Messages.getString("wav2vsq.finalPitchAverageLevel"),new String[]{"0","1","2","3","4","5","6","7","8","9","10","12","14","16","18","20","24","28","40","60","120","240"});
		finalPitchAverageLevel.setValue("40");
		finalPitchAverageLevel.setToolTipText(Messages.getString("wav2vsq.finalPitchAverageLevel_tooltip"));
		editor.addParamList(finalPitchAverageLevel);
		
		dynamicsAverageLevel = new ParamCombo(average,SWT.NULL,"dynamics_averageLevel",Messages.getString("wav2vsq.dynamics_averageLevel"),new String[]{"0","1","2","3","4","5","6","7","8","9","10","12","14","16","18","20","24","28","40","60","120","240"});
		dynamicsAverageLevel.setValue("60");
		dynamicsAverageLevel.setToolTipText(Messages.getString("wav2vsq.dynamics_averageLevel_tooltip"));
		editor.addParamList(dynamicsAverageLevel);
		
		
		
		
		Composite basic_middle=createSplitComposite(basicComposite,2,false,new GridData(GridData.FILL_HORIZONTAL));
		basic_middle.setLayout(LayoutBuilder.makeGridLayoutNoMargin(3, false));
		
		
		
		
		
		//combo
		min_picth=new ParamCombo(basic_upper,SWT.NULL,"min_pitch",Messages.getString("wav2midi.min_pitch"),new String[]{"0","40","60","80","100","150","200","300","400","500","600"});
		min_picth.setValue("80");	//for voice
		min_picth.setToolTipText(Messages.getString("wav2midi.min_pitch_tooltip"));
		editor.addParamList(min_picth);
		
		//combo
		max_pitch=new ParamCombo(basic_upper,SWT.NULL,"max_pitch",Messages.getString("wav2midi.max_pitch"),new String[]{"400","500","600","700","800","1000","1200","1400"});
		max_pitch.setValue("1000");
		max_pitch.setToolTipText(Messages.getString("wav2midi.max_pitch_tooltip"));
		editor.addParamList(max_pitch);
		
		
		
		
		
		//advanced composite
		Composite advance1=createSplitComposite(advancedComposite,4,false,new GridData(GridData.FILL_HORIZONTAL));
		advance1.setLayout(LayoutBuilder.makeGridLayoutNoMargin(4, false));
		ignoreOffsetBoolean = new ParamBoolean(advance1,SWT.NULL,"ignore_offset",Messages.getString("wav2midi.ignore_offset"));
		ignoreOffsetBoolean.setValue("1");
		editor.addParamList(ignoreOffsetBoolean);
		
		forceInsertSubtile = new ParamBoolean(advance1,SWT.NULL,"force_intsert",Messages.getString("wav2midi.force_intsert"));
		forceInsertSubtile.setValue("1");
		editor.addParamList(forceInsertSubtile);
		
		Composite advance3=createSplitComposite(advancedComposite,3,false,new GridData(GridData.FILL_HORIZONTAL));
		advance3.setLayout(LayoutBuilder.makeGridLayoutNoMargin(3, false));
		strechTimeSale = new ParamScale(advance3,SWT.NULL,"strech_time",Messages.getString("wav2midi.strech_time")){
			protected String toValue(String n){
				double num=Integer.parseInt(n);
				String ret=""+(double)getScale().getSelection()/10;
				while(ret.length()<num){
					ret=" "+ret;	
					}
				return ret;
			}
		};
strechTimeSale.setMinimum(3);
strechTimeSale.setMaximum(30);
strechTimeSale.setValue(10);
editor.addParamList(strechTimeSale);

		
minVolumeScale=new ParamSpinnerAndScale(advance3,SWT.NULL,"min_volume",Messages.getString("wav2midi.min_volume"));
minVolumeScale.setMinimum(1);
minVolumeScale.setMaximum(3000);
minVolumeScale.setValue(""+10);	//for catch no voice sounds
minVolumeScale.getSpinnerAndScale().getSpinner().setPageIncrement(5);
minVolumeScale.setToolTipText(Messages.getString("wav2midi.min_volume_tooltip"));
editor.addParamList(minVolumeScale);




noPitchMode = new ParamCombo(advance1,SWT.NULL,"nopitch_mode",Messages.getString("wav2midi.nopitch_mode"),new String[]{
	Messages.getString("wav2midi.nopitch_major"),
	Messages.getString("wav2midi.nopitch_average"),
	Messages.getString("wav2midi.nopitch_value"),
	Messages.getString("wav2midi.nopitch_after"),
	Messages.getString("wav2midi.nopitch_before"),
	
});
noPitchMode.setToolTipText(Messages.getString("wav2vsq.noPitchMode_tooltip"));
editor.addParamList(noPitchMode);

noPitchAlternative = new ParamCombo(advance1,SWT.NULL,"nopitch_mode_alternative",Messages.getString("wav2midi.nopitch_mode_alternative"),new String[]{
	Messages.getString("wav2midi.nopitch_major"),
	Messages.getString("wav2midi.nopitch_average"),
	Messages.getString("wav2midi.nopitch_value"),
	Messages.getString("wav2midi.nopitch_after"),
	Messages.getString("wav2midi.nopitch_before"),
	
});
editor.addParamList(noPitchAlternative);


Composite advance2=createSplitComposite(advancedComposite,5,false,new GridData(GridData.FILL_HORIZONTAL));
advance2.setLayout(LayoutBuilder.makeGridLayoutNoMargin(5, false));

String[] bendSenss=new String[24];
for (int i = 0; i < bendSenss.length; i++) {
	bendSenss[i]=""+(i+1);
}
bentSens=new ParamCombo(advance3,SWT.NULL,"bendSens",Messages.getString("wav2vsq.bend_sens"),bendSenss);
bentSens.setValue("8");
bentSens.setToolTipText(Messages.getString("wav2vsq.sbend_sens_tooltip"));
editor.addParamList(bentSens);





		
		
		
		
	    noteShiftScale=new ParamScale(basic_middle,SWT.NULL,"note_shift",Messages.getString("wav2midi.note_shift"));
	    noteShiftScale.setOffset(-24);
	    noteShiftScale.setMaximum(48);
	    noteShiftScale.setValue(0);
	    noteShiftScale.setToolTipText(Messages.getString("wav2midi.note_shift_tooltip"));
	    editor.addParamList(noteShiftScale);
	    
	    
	
		
		

		
		


		


		
		
		defaultNoteSpinner = new ParamSpinner(advance2,SWT.NULL,"default_pitch",Messages.getString("wav2midi.default_pitch"));
		defaultNoteSpinner.setMinimum(21);
		defaultNoteSpinner.setMaximum(108);
		defaultNoteSpinner.setValue(""+48);//C3
		 editor.addParamList(defaultNoteSpinner);


		
		
		roundPitch =  new ParamBoolean(advance2,SWT.NULL,"roundPitch",Messages.getString("wav2vsq.roundPitch"));
		roundPitch.setToolTipText(Messages.getString("wav2vsq.roundPitch_tooltip"));
		roundPitch.setValue("");
		 editor.addParamList(roundPitch);
		
		/* this is for MIDI
		setVelocityBoolean = new ParamBoolean(basic_upper,SWT.NULL,"ignore_offset",Messages.getString("wav2midi.set_velocity"));
		setVelocityBoolean.setValue("0");
		*/
		
	/*
		defaultVelocitySpinner = new ParamSpinner(advance2,SWT.NULL,"default_velocity",Messages.getString("wav2midi.default_velocity"));
		defaultVelocitySpinner.setMinimum(127);
		defaultVelocitySpinner.setMaximum(0);
		defaultVelocitySpinner.setValue(""+64);//center
		*/
		
		String[] preMeasures=new String[4];
		for (int i = 0; i < preMeasures.length; i++) {
			preMeasures[i]=""+(i+1);
		}
		preMeasure=new ParamCombo(advance2,SWT.NULL,"preMeasure",Messages.getString("wav2vsq.pre_measure"),preMeasures);
		preMeasure.setToolTipText(Messages.getString("wav2midi.pre_measure_tooltip"));
		 editor.addParamList(preMeasure);
		
		
		smoothLevel = new ParamCombo(advance2,SWT.NULL,"smoothLevel",Messages.getString("wav2vsq.smoothLevel"),new String[]{"1","2","4","8"});
		smoothLevel.setValue("2");
		smoothLevel.setToolTipText(Messages.getString("wav2vsq.smoothLevel_tooltip"));
		 editor.addParamList(smoothLevel);
		
			vocaloid1 =  new ParamBoolean(advance2,SWT.NULL,"vocaloid1",Messages.getString("wav2vsq.vocaloid1"));
			vocaloid1.setValue("");
			vocaloid1.setToolTipText(Messages.getString("wav2vsq.vocaloid1_tooltip"));
			//swap extension
			vocaloid1.setParamItemActionListener(new ParamItemActionListener(){
				@Override
				public void paramItemModified(ParamItem item) {
					if(outputFileChooser.getAbsoluteFilePath().endsWith(".vsq") && ((ParamBoolean)item).getBoolean()){
						String path=FileNameUtils.getChangedExtensionName(outputFileChooser.getAbsoluteFilePath(), "mid");
						outputFileChooser.setFilePath(path);
					}else if(outputFileChooser.getAbsoluteFilePath().endsWith(".mid") && !((ParamBoolean)item).getBoolean()){
						String path=FileNameUtils.getChangedExtensionName(outputFileChooser.getAbsoluteFilePath(), "vsq");
						outputFileChooser.setFilePath(path);
					}
				}});
			editor.addParamList(vocaloid1);
		
		Group blessGeneralGroup=new Group(breathComposite,SWT.NULL);
		blessGeneralGroup.setText(Messages.getString("wav2vsq.shared"));
		blessGeneralGroup.setLayout(LayoutBuilder.makeGridLayoutNoMargin(2, false));
		
		Group blessGroup=new Group(breathComposite,SWT.NULL);
		blessGroup.setText(Messages.getString("wav2vsq.separate"));
		blessGroup.setLayout(LayoutBuilder.makeGridLayoutNoMargin(4, false));
		
		Group blessCopyGroup=new Group(breathComposite,SWT.NULL);
		blessCopyGroup.setText(Messages.getString("wav2vsq.copy"));
		blessCopyGroup.setLayout(LayoutBuilder.makeGridLayoutNoMargin(5, false));
		
		ignoreBreathDynamics = new ParamBoolean(blessGeneralGroup,SWT.NULL,"fixed_breath_dynamics",Messages.getString("wav2vsq.fixed_breath_dynamics"));
		ignoreBreathDynamics.setValue("1");
		 editor.addParamList(ignoreBreathDynamics);
		
		fixedBreathDynamicsValue=new ParamScale(blessGeneralGroup,SWT.NULL,"fixed_breath_dynamics_value",Messages.getString("wav2vsq.fixed_breath_dynamics_value"));
		fixedBreathDynamicsValue.setMaximum(127);
		fixedBreathDynamicsValue.setValue(48);
		 editor.addParamList(fixedBreathDynamicsValue);

		
		
		splitBlessTrack = new ParamBoolean(blessGroup,SWT.NULL,"split_breath_track",Messages.getString("wav2vsq.split_breath_track"));
		splitBlessTrack.setValue("1");
		 editor.addParamList(splitBlessTrack);
		 
		 doubleBreathTrack_split = new ParamBoolean(blessGroup,SWT.NULL,"double_breath_track_split",Messages.getString("wav2vsq.double_breath_track"));
		 editor.addParamList(doubleBreathTrack_split);
		 
		copyAsBlessTrack = new ParamBoolean(blessCopyGroup,SWT.NULL,"copy_as_breath_track",Messages.getString("wav2vsq.copy_as_breath_track"));
		 editor.addParamList(copyAsBlessTrack);
		 
		copyAsBreathPhonetics = new ParamCombo(blessCopyGroup,SWT.NULL,"copy_as_breath_phonetics",Messages.getString("wav2vsq.copy_as_breath_phonetics"),new String[]{
			"br1",
			"br2",
			"br3",
			"br4",
			"br5"
		});
		copyAsBreathPhonetics.setValue("br4");
		 editor.addParamList(copyAsBreathPhonetics);
		 
		copyAsBreathPhonetics2 = new ParamCombo(blessCopyGroup,SWT.NULL,"copy_as_breath_phonetics2",Messages.getString("wav2vsq.copy_as_breath_phonetics2"),new String[]{
			"br1",
			"br2",
			"br3",
			"br4",
			"br5"
		});
		copyAsBreathPhonetics2.setValue("br5");
		 editor.addParamList(copyAsBreathPhonetics2);
		 
		 doubleBreathTrack = new ParamBoolean(blessCopyGroup,SWT.NULL,"double_breath_track",Messages.getString("wav2vsq.double_breath_track"));
		 editor.addParamList(doubleBreathTrack);
		 
		 
		Group phoneticsGroup=new Group(advancedComposite,SWT.NULL);
		phoneticsGroup.setText(Messages.getString("wav2vsq.vocaloid_phonetics"));
		phoneticsGroup.setLayout(LayoutBuilder.makeGridLayoutNoMargin(4, false));

		autoNPhonetics = new ParamBoolean(phoneticsGroup,SWT.NULL,"auto_nn_phonetics",Messages.getString("wav2vsq.auto_nn_phonetics"));
		autoNPhonetics.setValue("1");
		 editor.addParamList(autoNPhonetics);
		 
		dynamicOverdrive = new ParamCombo(basic_upper,SWT.NULL,"dynamic_overdrive",Messages.getString("wav2midi.dynamic_overdrive"),new String[]{
			"+4 95%"
			,"",
			"200%",
			"150%",
			"120%",
			"100%",
			"90%",
			"75%",
			"50%",
			"+16",
			"+32",
			"+64",
			"x1.2",
			"x1.5",
			"x2.0",
			"x3.0",
			"+12 80%",
			"+4 90%",
			"+4 100%",
			"+4 120%",
			"+4 150%"
		});
		dynamicOverdrive.setToolTipText(Messages.getString("wav2vsq.dynamicOverdrive_tooltip"));
		 editor.addParamList(dynamicOverdrive);
		 
		Composite track1=createSplitComposite(trackComposite,5,false,new GridData(GridData.FILL_HORIZONTAL));
		
		Composite track2=createSplitComposite(trackComposite,5,false,new GridData(GridData.FILL_HORIZONTAL));
		
	
		
		filterCodeCombo = new ParamCombo(track1,SWT.NULL,"filter_code",Messages.getString("wav2midi.filter_code"),new String[]{
			"","C","C"+Scale.LABEL_MAJOR,"C"+Scale.LABEL_MAJOR_SEVEN,"C"+Scale.LABEL_SEVEN,"C"+Scale.LABEL_AUG,"C"+Scale.LABEL_FLAT_FIVE,
			"C"+Scale.LABEL_SIX,"C"+Scale.LABEL_MAJOR_NINES,"C"+Scale.LABEL_SEVEN_FLAT_FIVE,"C"+Scale.LABEL_SEVEN_AUG,"C"+Scale.LABEL_SIX_NINE,
			"C"+Scale.LABEL_NINES,"C"+Scale.LABEL_SEVEN_FLAT_NINES,"C"+Scale.LABEL_MINOR,"C"+Scale.LABEL_ROOT
		});
		filterCodeCombo.setIgnoreOne(true);
		 editor.addParamList(filterCodeCombo);
		
		upfilterCodeCombo = new ParamCombo(track1,SWT.NULL,"filter_up",Messages.getString("wav2midi.filter_up"),new String[]{
			"","C","C"+Scale.LABEL_MAJOR,"C"+Scale.LABEL_MAJOR_SEVEN,"C"+Scale.LABEL_SEVEN,"C"+Scale.LABEL_AUG,"C"+Scale.LABEL_FLAT_FIVE,
			"C"+Scale.LABEL_SIX,"C"+Scale.LABEL_MAJOR_NINES,"C"+Scale.LABEL_SEVEN_FLAT_FIVE,"C"+Scale.LABEL_SEVEN_AUG,"C"+Scale.LABEL_SIX_NINE,
			"C"+Scale.LABEL_NINES,"C"+Scale.LABEL_SEVEN_FLAT_NINES,"C"+Scale.LABEL_MINOR,"C"+Scale.LABEL_ROOT
		});
		upfilterCodeCombo.setIgnoreOne(true);
		 editor.addParamList(upfilterCodeCombo);
		 
		upMixerScale=new ParamCombo(track1,SWT.NULL,"up_mixer",Messages.getString("wav2vsq.up_mixer"),new String[]{"0","-10.0","-15","-20.0","-30","-40.0"});
		upMixerScale.setValue("-20.0");
		 editor.addParamList(upMixerScale);
		 
		downfilterCodeCombo = new ParamCombo(track1,SWT.NULL,"filter_down",Messages.getString("wav2midi.filter_down"),new String[]{
			"","C","C"+Scale.LABEL_MAJOR,"C"+Scale.LABEL_MAJOR_SEVEN,"C"+Scale.LABEL_SEVEN,"C"+Scale.LABEL_AUG,"C"+Scale.LABEL_FLAT_FIVE,
			"C"+Scale.LABEL_SIX,"C"+Scale.LABEL_MAJOR_NINES,"C"+Scale.LABEL_SEVEN_FLAT_FIVE,"C"+Scale.LABEL_SEVEN_AUG,"C"+Scale.LABEL_SIX_NINE,
			"C"+Scale.LABEL_NINES,"C"+Scale.LABEL_SEVEN_FLAT_NINES,"C"+Scale.LABEL_MINOR,"C"+Scale.LABEL_ROOT
		});
		downfilterCodeCombo.setIgnoreOne(true);
		 editor.addParamList(downfilterCodeCombo);
		 
		downMixerScale=new ParamCombo(track1,SWT.NULL,"down_mixer",Messages.getString("wav2vsq.down_mixer"),new String[]{"0","-10.0","-15","-20.0","-30","-40.0"});
		downMixerScale.setValue("-20.0");
		 editor.addParamList(downMixerScale);
		 
		 
		makeStereoTrack =  new ParamBoolean(track2,SWT.NULL,"make_stereo",Messages.getString("wav2vsq.make_stereo"));
		makeStereoTrack.setValue("");
		 editor.addParamList(makeStereoTrack);
		 
		 
		stereoMixerScale=new ParamCombo(track2,SWT.NULL,"stereo_mixer",Messages.getString("wav2vsq.stereo_mixer"),new String[]{"0","-10.0","-15","-20.0","-30","-40.0"});
		stereoMixerScale.setValue("-8.0");
		 editor.addParamList(stereoMixerScale);
		 
		stereoPanScale=new ParamScale(track2,SWT.NULL,"stereo_pan",Messages.getString("wav2vsq.stereo_pan"));
		stereoPanScale.setMaximum(64);
		stereoPanScale.setValue(64);
		 editor.addParamList(stereoPanScale);
		 
		//voice
		Composite voice1=createSplitComposite(voiceComposite,2,false,new GridData(GridData.FILL_HORIZONTAL));
		Composite voiceSettings=WidgetBuilder.createTwoGridLayoutComposite(voice1, SWT.NULL) ;
		VoiceSettingList voiceSettingList=new VoiceSettingList(voice1,SWT.NULL,VoiceSettingPage.PREFERENCE_KEY,Akj_betasPlugin.getDefault().getPreferenceStore(),"voice_setting");
		voiceSettingList.setLayoutData(new GridData(GridData.FILL_BOTH));
		DefaultParamOptionEditor voice_editor=new DefaultParamOptionEditor();
		voiceSettingList.createControls(voice_editor);
		editor.addParamList(voiceSettingList);
		
		velScale=new ParamScale(voiceSettings,SWT.NULL,"vel",Messages.getString("wav2vsq.vel"));
		velScale.setMaximum(127);
		velScale.setValue(64);
		voice_editor.addParamList(velScale);
		
		breScale=new ParamScale(voiceSettings,SWT.NULL,"bre",Messages.getString("wav2vsq.bre"));
		breScale.setMaximum(127);
		breScale.setValue(0);
		voice_editor.addParamList(breScale);
		
		briScale=new ParamScale(voiceSettings,SWT.NULL,"bri",Messages.getString("wav2vsq.bri"));
		briScale.setMaximum(127);
		briScale.setValue(64);
		voice_editor.addParamList(briScale);
		
		cleScale=new ParamScale(voiceSettings,SWT.NULL,"cle",Messages.getString("wav2vsq.cle"));
		cleScale.setMaximum(127);
		cleScale.setValue(0);
		voice_editor.addParamList(cleScale);
		
		opeScale=new ParamScale(voiceSettings,SWT.NULL,"ope",Messages.getString("wav2vsq.ope"));
		opeScale.setMaximum(127);
		opeScale.setValue(127);
		voice_editor.addParamList(opeScale);
		
		genScale=new ParamScale(voiceSettings,SWT.NULL,"gen",Messages.getString("wav2vsq.gender"));
		genScale.setMaximum(127);
		genScale.setValue(64);
		voice_editor.addParamList(genScale);
		
		porScale=new ParamScale(voiceSettings,SWT.NULL,"por",Messages.getString("wav2vsq.por"));
		porScale.setMaximum(127);
		porScale.setValue(64);
		voice_editor.addParamList(porScale);
		
		

	    settingList.tableSelectionChanged();//for sync values
		//
		
		inputWavFileChooser = new FileDirChoicer(parent,SWT.BORDER,FileDirChoicer.FILE,Messages.getString("wav2midi.wave"));
		inputWavFileChooser.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		inputWavFileChooser.addFileListChangeListener(selectedListener);
		inputWavFileChooser.setFilterExtensions(new String[]{"*.wav"});
		inputWavFileChooser.addFileListChangeListener(new ExportFileSet());
		
		inputSrtFileChooser = new FileDirChoicer(parent,SWT.BORDER,FileDirChoicer.FILE,Messages.getString("wav2midi.srt"),true);
		inputSrtFileChooser.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		inputSrtFileChooser.addFileListChangeListener(selectedListener);
		inputSrtFileChooser.setFilterExtensions(new String[]{"*.srt"});
		
		
		Composite outputs=WidgetBuilder.createTwoGridLayoutComposite(parent, SWT.NULL);
		outputs.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		Button sameAsInput=new Button(outputs,SWT.NULL);
		sameAsInput.setText(Messages.getString("wav2midi.sameInInput"));
		sameAsInput.addSelectionListener(new SelectionListener(){

			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
				
			}

			@Override
			public void widgetSelected(SelectionEvent e) {
				if(!inputWavFileChooser.getAbsoluteFilePath().equals("")){
					syncInputAndOutput(inputWavFileChooser.getAbsoluteFilePath(),true);
				}
				
			}
			});
		outputFileChooser = new FileDirChoicer(outputs,SWT.BORDER,FileDirChoicer.SAVE,Messages.getString("wav2midi.export_vsq"),true);
		outputFileChooser.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		outputFileChooser.setFilterExtensions(new String[]{"*.vsq","*.mid"});
		outputFileChooser.addFileListChangeListener(selectedListener);
		
		
		
		wavToMidiExecuter.addControl(inputWavFileChooser);
		wavToMidiExecuter.addControl(inputSrtFileChooser);
		wavToMidiExecuter.addControl(outputFileChooser);
		
		Composite exec_label=WidgetBuilder.createGridLayoutComposite(parent,SWT.NULL,3, false);
		exec_label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		ExecutingControlButton exec=new ExecutingControlButton(exec_label,SWT.NULL,wavToMidiExecuter,
				Messages.getString("wav2midi.convert_vsq"),Messages.getString("cancel"));
		
		statusLabel = new Label(exec_label,SWT.NULL);
		statusLabel.setForeground(new Color(null,new RGB(255,0,0)));
		statusLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		
		Button openWaveForm=new Button(exec_label,SWT.NULL);
		openWaveForm.setText(Messages.getString("wav2vsq.open_WaveFormViewer"));
		openWaveForm.addSelectionListener(new SelectionListener(){

			@Override
			public void widgetDefaultSelected(SelectionEvent e) {

			}

			@Override
			public void widgetSelected(SelectionEvent e) {
				openWavFormViewer();
			}});
		updateStatus();
		
		new DropMonitor(parent);
	}
	
	public class SettingMonitor implements IPropertyChangeListener {

		public void propertyChange(PropertyChangeEvent event) {
			log.info(event.getProperty());
			if (event.getProperty().equals(OtherToolsSettingPage.PATH_ASCII_TEMPORARY)) {
				updateStatus();
			} 
		}
	}
	
	public void setFocus() {
		
	}
	public void updateStatus() {
		//update label.
		if(wavToMidiExecuter.canExecute()){
			if(new File(outputFileChooser.getAbsoluteFilePath()).exists()){
				statusLabel.setText(Messages.getString("wav2midi.warn_overwrite"));
			}else{
			statusLabel.setText("");
			}
		}else{
			if(tmpDirChooser.getAbsoluteFilePath().equals("") || !FileNameUtils.isAsciiFileName(tmpDirChooser.getAbsoluteFilePath())){
				statusLabel.setText(Messages.getString("wav2midi.choose_tmpdir"));
			}else if(inputWavFileChooser.getAbsoluteFilePath().equals("")){
				statusLabel.setText(Messages.getString("wav2vsq.choose_input"));
			}else if(outputFileChooser.getAbsoluteFilePath().equals("")){
				statusLabel.setText(Messages.getString("wav2vsq.choose_output"));
			}
		}
		
		// enable buttons and status.
		wavToMidiExecuter.updateControlSwitch();
	}
	private Composite createSplitComposite(Composite parent,int split,boolean same,Object data){
		Composite composite=new Composite(parent,SWT.NULL);
		composite.setLayout(new GridLayout(split,same));
		if(data!=null){
			composite.setLayoutData(data);
		}
		return composite;
	}
	private ParamTextArea createGridTextAreaGroup(Composite parent,String key,String label,Object data){
		/*Group group=new Group(parent,SWT.NULL);
		group.setText(label);
		group.setLayout(new FillLayout());
		group.setLayoutData(data);
		Text text=new Text(group,SWT.MULTI|SWT.V_SCROLL|SWT.H_SCROLL|SWT.BORDER);
		*/
		
		ParamTextArea text=new ParamTextArea(parent,SWT.NULL,key,label,ParamText.LAYOUT_FILL_BOTH);
		text.setLayoutData(data);
		return text;
	}
	
	private ParamText createLabeldText(Composite parent,String key,String label,Object data){
		ParamText text=new ParamText(parent,SWT.NULL,key,label,ParamText.LAYOUT_FILL_HORIZONTAL);
		if(data!=null){
			text.setLayoutData(data);
		}
		return text;
	}
	
	public class WavToVocaloidMIDIExecute extends ExecutingControler{
		
		private int min_pitch_value;
		private int max_pitch_value;
		private int min_volume_value;
		private int note_shift_value;
		private String inputWaveFileChooser_value;
		private String inputSrtFileChooser_value;
		
		private String outputFileChooser_value;
		
		private String tmpDirChooser_value;
		private boolean forceInsert;
		private boolean ignoreOffset;
		private double strechPlayTime;
		//private boolean setVelocity;
		private boolean setPitch;
		private boolean velocityDetail;
		private boolean pitchDetail;
		private int defaultNote;
		
		private String scale_key;
		
		private String up_scale_key;
		
		private String down_scale_key;
		private String chorus_key;
		
		private int preMeasure_value;
		private int bentSens_value;
		private int gender;
		private int vel;

		private int bre;
		private int bri;
		
		private int cle;
		private int ope;
		private int por;
		private int smoothLevel_value;
		
		private int noPitchMode_value;
		private int noPitchAltenative_value;
		
		private int downMixer;
		private int upMixer;
		private int pitchAverageLevel;
		private int volumeAverageLevel;
		
		private boolean containPitchOverRange;
		private int finalNormalizePitchRange;
		
		private String strategy;
		
		private boolean makeStereoTrack_value;
		
		private boolean copyAsBreathTrack_value;
		private String copyAsBreathPhonetics_value;
		private String copyAsBreathPhonetics_value2;
		private boolean separateBreathTrack_value;
		private boolean fixBreathTrack=true;
		private int fixBreathTrackValue_value=48;
		private boolean doubleBreathTrack_value;
		private boolean doubleBreathTrack_split_value;
		private int stereoMixer;
		private int stereoPan;
		
		private boolean autoNNConvert;
		public void afterExecute() {
			
		}

		@Override
		public void beforeExecute() {
			log.info("beforeExecute");
			try{
			min_pitch_value=Integer.parseInt(min_picth.getValue());
			
			if(min_pitch_value==0){
				min_pitch_value=60;
			}
			try{
			max_pitch_value=Integer.parseInt(max_pitch.getValue());
			}catch(Exception e){
				
			}
			if(max_pitch_value==0){
				max_pitch_value=600;
			}
			
			forceInsert=forceInsertSubtile.getBoolean();
			ignoreOffset=ignoreOffsetBoolean.getBoolean();
			strechPlayTime=Double.parseDouble(strechTimeSale.getValue())/10;
			
			min_volume_value=(int) Double.parseDouble(minVolumeScale.getValue());
			note_shift_value=(int) Double.parseDouble(noteShiftScale.getValue());
			
			//setVelocity=setVelocityBoolean.getBoolean();
			
			velocityDetail=setVelocityDetailBoolean.getBoolean();
			
			setPitch=setPitchBoolean.getBoolean();
			pitchDetail=setPitchDetailBoolean.getBoolean();
			defaultNote=(int) Double.parseDouble(defaultNoteSpinner.getValue());
			//defaultVelocity=(int) Double.parseDouble(defaultVelocitySpinner.getValue());
			
	
			
			inputWaveFileChooser_value=inputWavFileChooser.getAbsoluteFilePath();
			inputSrtFileChooser_value=inputSrtFileChooser.getAbsoluteFilePath();
			outputFileChooser_value=outputFileChooser.getAbsoluteFilePath();
			
			tmpDirChooser_value=tmpDirChooser.getAbsoluteFilePath();
			
			preMeasure_value=Integer.parseInt(preMeasure.getValue());
			bentSens_value=Integer.parseInt(bentSens.getValue());
			
			
			vel=(int) Double.parseDouble(velScale.getValue());
			bre=(int) Double.parseDouble(breScale.getValue());
			bri=(int) Double.parseDouble(briScale.getValue());
			cle=(int) Double.parseDouble(cleScale.getValue());
			ope=(int) Double.parseDouble(opeScale.getValue());
			gender=(int) Double.parseDouble(genScale.getValue());
			por=(int) Double.parseDouble(porScale.getValue());
			smoothLevel_value=(int) Double.parseDouble(smoothLevel.getValue());
			
			scale_key=filterCodeCombo.getValue();
			up_scale_key=upfilterCodeCombo.getValue();
			down_scale_key=downfilterCodeCombo.getValue();
			
			noPitchMode_value=noPitchMode.getSelection();
			noPitchAltenative_value=noPitchAlternative.getSelection();
			
			downMixer=(int) (Double.parseDouble(downMixerScale.getValue())*10);
			upMixer=(int) (Double.parseDouble(upMixerScale.getValue())*10);
			
			pitchAverageLevel=toInt(averageLevel.getValue());
			
			volumeAverageLevel=toInt(dynamicsAverageLevel.getValue());
			
			containPitchOverRange=roundPitch.getBoolean();
			
			finalNormalizePitchRange=toInt(finalPitchAverageLevel.getValue());
			
			
			strategy=dynamicOverdrive.getValue();
			
			//stereo
			makeStereoTrack_value=makeStereoTrack.getBoolean();
			stereoMixer=(int) (Double.parseDouble(stereoMixerScale.getValue())*10);
			stereoPan=(int) (Double.parseDouble(stereoPanScale.getValue()));
			
			//do breath
			copyAsBreathTrack_value=copyAsBlessTrack.getBoolean();
			separateBreathTrack_value=splitBlessTrack.getBoolean();
			copyAsBreathPhonetics_value=copyAsBreathPhonetics.getValue();
			copyAsBreathPhonetics_value2=copyAsBreathPhonetics2.getValue();
			
			fixBreathTrack=ignoreBreathDynamics.getBoolean();
			fixBreathTrackValue_value=toInt(fixedBreathDynamicsValue.getValue());
			
			doubleBreathTrack_value=doubleBreathTrack.getBoolean();
			doubleBreathTrack_split_value=doubleBreathTrack_split.getBoolean();
			autoNNConvert=autoNPhonetics.getBoolean();
			}catch(Exception e){
				throw new RuntimeException("invalid param");
			}
		}

		private int toInt(String value) {
			try{
			return Integer.parseInt(value);
			}catch(Exception e){
				return 0;
			}
		}

		@Override
		public boolean canExecute() {
			if(!FileNameUtils.isAsciiFileName(tmpDirChooser.getAbsoluteFilePath())){
				return false;
			}
			return !inputSrtFileChooser.getAbsoluteFilePath().equals("") && !inputWavFileChooser.getAbsoluteFilePath().equals("") &&!outputFileChooser.getAbsoluteFilePath().equals("") ;
			
		}

		@Override
		public void cancelExecuting() {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void inExecute() {
			log.info("inExecute");
			String pitch2ExePath=Akj_betasPlugin.getDefault().getPreferenceStore().getString(AudioToolsSettingPage.PATH_PITCH2);
			if(pitch2ExePath.equals("")){
				StatusBarUtils.showStatusBar("pitch2.exe is not setted in OtherTools setting");
				return;
			}
			File output=new File(outputFileChooser_value);
			
			File waveFile=new File(inputWaveFileChooser_value);
			AudioFileFormat format=null;
			try {
				format=AudioSystem.getAudioFileFormat(waveFile);
			} catch (UnsupportedAudioFileException e1) {
				e1.printStackTrace();
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			
			if(format==null){
				//mea
				log.warn("wrong wave");
				return;
			}
			
			
			File input;
			File tmp=null;
			if(FileNameUtils.isAsciiFileName(inputWaveFileChooser_value) &&(int)format.getFormat().getSampleRate()==48000){
			input=new File(inputWaveFileChooser_value);
			}else{
			input=new File(tmpDirChooser_value,System.currentTimeMillis()+".wav");
			tmp=input;
			tmp.deleteOnExit();
			if((int)format.getFormat().getSampleRate()==48000){
				try {
					FileUtils.copyFile(waveFile, input);
				} catch (IOException e) {
					e.printStackTrace();
				}
			}else{
				String ffmpeg=FFMpegUI.getFFmpegOrPureFFMpeg();
				if(ffmpeg==null){
					log.warn("no ffmpeg and copy");
					try {
						FileUtils.copyFile(waveFile, input);
					} catch (IOException e) {
						e.printStackTrace();
					}
				}else{
					SimpleCommandExecuter executer=new SimpleCommandExecuter(FFMpegCommandUtil.makeWaveSampleRateChangeCommand(ffmpeg, waveFile.getAbsolutePath(), input.getAbsolutePath(), 48000));
					executer.setPrinter(Akj_betasPlugin.getDefault().getProcessPrinter());//for debug
					executer.execute();
					StatusBarUtils.showStatusBar("");
					}
				}
			}
			
			PitchExecuter executer=new PitchExecuter();
			executer.setPitch2ExePath(pitch2ExePath);
			
			int detailLevel=smoothLevel_value;//how smooth pitch,values 1,2,4,8
			double pitchTime=0.03125/(2*detailLevel);
			ESPS[] esps;
			try {
			
				String commands[]=executer.getCommands(input.getAbsolutePath(), 0, 0,min_pitch_value,max_pitch_value,0.03125/(2*detailLevel));// 1/64 = 0.03125/2
				log.info(FFMpegUtils.toPrintCommand(commands));
				Akj_betasPlugin.getDefault().getProcessPrinter().printOutput("###\n"+FFMpegUtils.toPrintCommand(commands)+"\n");
				esps = executer.getESPS(input.getAbsolutePath(), 0, 0,min_pitch_value,max_pitch_value,0.03125/(2*detailLevel));
				
				
				
				
				
				//esps=SnackExecuter.toAverage(esps,2);
				PitchToVocaloidMIDI p2midi=new PitchToVocaloidMIDI();
				p2midi.setDetailLevel(detailLevel);
				
				p2midi.setShiftNote(note_shift_value);
				p2midi.setVolumeMin(min_volume_value);
				
				p2midi.setIgnoreOffset(ignoreOffset);
				p2midi.setForceInsert(forceInsert);
				
				p2midi.setParseNote(setPitch);
				
				
				p2midi.setDefaultNote(defaultNote);
				p2midi.setDefaultVelocity(vel);
				
				p2midi.setPreMeasure(preMeasure_value);
				p2midi.setMaxBendSens(bentSens_value);
				
				
				p2midi.setBre(bre);
				p2midi.setBri(bri);
				p2midi.setCle(cle);
				p2midi.setOpe(ope);
				
				p2midi.setGen(gender);
				p2midi.setPor(por);
				
				p2midi.setDetailDynamics(velocityDetail);
				p2midi.setDetailPitch(pitchDetail);
				
				//how set no voice value.
				p2midi.setNoPitchMode(noPitchMode_value);
				p2midi.setNoPitchAlternativeMode(noPitchAltenative_value);
				/*
				 * chrus seems not work yet.now work midi only
				chorus_key="1+3+5";
				if(StringUtils.isNotEmpty(chorus_key)){
					p2midi.setChorusLine(chorus_key);
				}
				*/
				
				
				if(StringUtils.isNotEmpty(scale_key)){
					int codes[]=Scale.getCodeScale(scale_key);//start with 1
					p2midi.setScaleFilter(codes);
				}
				
				if(StringUtils.isNotEmpty(up_scale_key)){
					int codes[]=Scale.getCodeScale(up_scale_key);
					p2midi.setUpHamoriScale(codes);
					p2midi.setUpMixer(upMixer);
				}
				
				if(StringUtils.isNotEmpty(down_scale_key)){
					int codes[]=Scale.getCodeScale(down_scale_key);
					p2midi.setDownHamoriScale(codes);
					p2midi.setDownMixer(downMixer);
				}
				
				//is average pitch dynamics
				if(pitchAverageLevel>0){
					p2midi.setNormalizePitch(true);
					p2midi.setNormalizePitchRange(pitchAverageLevel);
				}else{
					p2midi.setNormalizePitch(false);
				}
				
				if(volumeAverageLevel>0){
					p2midi.setNormalizeVolume(true);
					p2midi.setNormalizeVolumeRange(volumeAverageLevel);
				}else{
					p2midi.setNormalizeVolume(false);
				}
				
				if(finalNormalizePitchRange>0){
					p2midi.setFinalNormalizePitch(true);
					p2midi.setFinalNormalizePitchRange(finalNormalizePitchRange);
				}else{
					p2midi.setFinalNormalizePitch(false);
					p2midi.setFinalNormalizePitchRange(0);
				}
				p2midi.setContainPitchOverRange(containPitchOverRange);//for round corner.
				
				if(!strategy.equals("")){
					p2midi.setDynamicChangeStrategy(strategy);
				}
				
				
				p2midi.setTempo((int) (120/strechPlayTime));
				
				//stereo
				p2midi.setAddStereoTrack(makeStereoTrack_value);
				p2midi.setStereoTrackMixer(stereoMixer);
				p2midi.setStereoTrackPan(stereoPan);
				
				
				
				//breath
				p2midi.setCopyAsBreathTrack(copyAsBreathTrack_value);
				p2midi.setSeparateBreathTrack(separateBreathTrack_value);
				p2midi.setCopyAsBreathPhonetics(copyAsBreathPhonetics_value);
				p2midi.setCopyAsBreathPhonetics2(copyAsBreathPhonetics_value2);
				p2midi.setDoubleBreathTrack(doubleBreathTrack_value);
				p2midi.setDoubleBreathOnSplit(doubleBreathTrack_split_value);
				p2midi.setIgnoreBreathDynamics(fixBreathTrack);
				p2midi.setDefaultBreathDynamics(fixBreathTrackValue_value);
				//log.info(ignoreOffset+","+forceInsert+","+strechPlayTime);
				
				p2midi.setAutoNNPhonetics(autoNNConvert);
				
				StatusBarUtils.showStatusBar("");
				
				if(!inputSrtFileChooser_value.equals("")){
				StandardSubObject[] subtitles=loadSubtitles(new File(inputSrtFileChooser_value));
				subtitles=filterESPSes(esps,subtitles,pitchTime);
				p2midi.makeVocaloidMIDI(esps, subtitles,output);
				}else{
				throw new IOException("never");
				
				}
				
				StatusBarUtils.showStatusBar(Messages.getString("wav2vsq.created")+output.getName());
				if(tmp!=null){
					tmp.delete();
				}
			} catch (IOException e) {
				StatusBarUtils.showStatusBar("faild:"+output.getName());
				Akj_betasPlugin.getDefault().getProcessPrinter().printOutput(e.getMessage()+"\n");
				e.printStackTrace();
			}
			
			Akj_betasPlugin.getDefault().getProcessPrinter().printOutput("###\n");
			
			
		}
		
		
	}
	public StandardSubObject[] loadSubtitles(File file){
		if(file==null || !file.exists()){
			return new StandardSubObject[0];
		}
		SRTParser parser=new SRTParser();
		SRTList list;
		try {
			list = SubtitleUtils.loadSrt(file, DetectUtils.ENCODING_MS932);
			List<StandardSubObject> subList=list.convertStandardSubtitleDataList();
			return subList.toArray(new StandardSubObject[subList.size()]);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		 return new StandardSubObject[0];
	}

	/*
	 * process ignore * data
	 */
	public StandardSubObject[] filterESPSes(ESPS[] esps, StandardSubObject[] subtitles,double pitchTime) {
		List<StandardSubObject> ret=new ArrayList<StandardSubObject>();
		for (int i = 0; i < subtitles.length; i++) {
			if(subtitles[i].getText().equals(IGNORE_AREA_MARK)){
				int startIndex=(int) ((subtitles[i].getStartTime()/1000.0-PitchExecuter.SKIPPED_TIME)/pitchTime);
				int endIndex=(int) ((subtitles[i].getEndTime()/1000.0-PitchExecuter.SKIPPED_TIME)/pitchTime);
				System.out.println("start="+startIndex+",end="+endIndex);
				for (int j = startIndex; j < endIndex; j++) {
					if(j<esps.length){
						esps[j].setPitch(0);
						esps[j].setVoicing(false);
						esps[j].setMeasurements(0);
					}
				}
			}else{
				ret.add(subtitles[i]);
			}
		}
		return ret.toArray(new StandardSubObject[ret.size()]);
	}

	public class FileSelected implements FileStatusChangeListener{

		public void addList(FileStatusChangeEvent event) {
			
			updateStatus();
		}

		public void removeList(FileStatusChangeEvent event) {
			updateStatus();
		}
		
	}
	

	public class DropMonitor extends DropTargetAdapter {
		public DropMonitor(Composite controler){
			Transfer[] types = new Transfer[] { FileTransfer.getInstance() };

			int operations = DND.DROP_MOVE | DND.DROP_COPY;

			DropTarget target2 = new DropTarget(controler, operations);
			target2.setTransfer(types);

			target2.addDropListener(this);
		}
		public void dragEnter(DropTargetEvent event) {
			// log.infodrag enter:"+event.data);
		}

		public void dragOver(DropTargetEvent event) {
			// log.infodrag over:"+event.data);
		}

		public void drop(DropTargetEvent event) {
			//log.info("cancovert:"+isCanConvert());
					
			String files[] = (String[]) event.data;

			
			for (int i = 0; i < files.length; i++) {
				
				if(FileNameUtils.isWaveFile(files[i]) && new File(files[i]).isFile()){
				inputWavFileChooser.setFilePath(files[i]);
				setInputWave(files[i]);
				break;	//now first 1 file only
				}else if(FileNameUtils.getExtension(files[i]).toLowerCase().equals("vsq")){
					outputFileChooser.setFilePath(files[i]);
					wavToMidiExecuter.updateControlSwitch();
					break;
				}
			}
			
		}
	}
	
	public void setInput(String path){
		inputWavFileChooser.setFilePath(path);
		setInputWave(path);
	}
	
	public void setSubtitle(String path){
		inputSrtFileChooser.setFilePath(path);
	}
	
	public void setPitchAnalyzeSetting(int detailLevel,int minPitch,int maxPitch,String minLevel){
		smoothLevel.setValue(""+detailLevel);
		min_picth.setValue(""+minPitch);
		max_pitch.setValue(""+maxPitch);
		minVolumeScale.setValue(minLevel);
	}
	

	private void syncInputAndOutput(String path,boolean overwrite){
		String exportPath;
		if(vocaloid1.getBoolean()){
			exportPath=FileNameUtils.getChangedExtensionName(new File(path), "mid",true);
		}else{
			exportPath=FileNameUtils.getChangedExtensionName(new File(path), "vsq",true);
		}
		
		boolean fileExist=new File(exportPath).exists();
		if(!fileExist || overwrite){//dont overwrite automatic
			outputFileChooser.setFilePath(exportPath);
			
		}
		updateStatus();
	}
	private void setInputWave(String path) {
	
		syncInputAndOutput(path,false);
		
		String srtPath=FileNameUtils.getChangedExtensionName(new File(path), "srt",true);
		if(new File(srtPath).exists()){//dont overwrite automatic
			inputSrtFileChooser.setFilePath(srtPath);
		}
		updateStatus();
	}
	
	protected void openWavFormViewer(){
		WaveFormViewer part;
		try {
			part = (WaveFormViewer) PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().showView(WaveFormViewer.ID);
			int detail=Integer.parseInt(smoothLevel.getValue());
			int min=Integer.parseInt(min_picth.getValue());
			int max=Integer.parseInt(max_pitch.getValue());
			int volumeLevel=(int) Double.parseDouble(minVolumeScale.getValue());
			part.setPitchAnalyzeSetting(detail, min, max,volumeLevel);
			String audio=inputWavFileChooser.getAbsoluteFilePath();
			if(audio.length()>0){
				File f=new File(audio);
				if(f.exists()){
					part.openFile(f);
					String srt=inputSrtFileChooser.getAbsoluteFilePath();
					if(srt.length()>0){
						File s=new File(srt);
						if(s.exists()){
							part.loadSRT(s);
						}
					}
				}
			}
			//set min,max detail
		} catch (PartInitException en) {
			// TODO Auto-generated catch block
			en.printStackTrace();
		}
		}
	
		
}